// 遍历数据,执行回调
/*
** 遍历由对象和数组为结构的数据, 直到遍历到非对象或非数组，同时通过path缓存遍历路径, 执行回调
** 方法主要用于数据结构的转换
*/

function isObject (obj){
	return Object.prototype.toString.call(obj) === '[object Object]';
}

function isArray (arr){
    return Object.prototype.toString.call(arr) === '[object Array]';
}

// 遍历对象
function loopData (beLoop, fn, path=""){

    let loop = {};
    let isObj = true;

    if(isObject(beLoop)){
        
        loop = Object.keys(beLoop)
    
    }else if(isArray(beLoop)){

        loop = beLoop;
        isObj = false;
    
    }else{

        console.log('循环对象类型错误', beLoop)
        return beLoop;
    }

    loop.forEach((item, index) =>{

        let delimiter = path ? '-' : '';
        
        let history = isObj ? item : index;
        let data = isObj ? beLoop[item] : item;
        let pathHistory = path + delimiter + history;
            
        if(isObject(data) || isArray(data)){
            loopData(data, fn, pathHistory)
        }else{
            fn(beLoop, item, pathHistory, data);
        }

    })
}

// 重构
function restructure(data){
    let cache = {};

    loopData(data, (beLoop, item, pathHistory, data) =>{
        cache[pathHistory] = data;
    })
    return cache
} 

// 生成映射表
function creatMap(source, target){
    let map = {};
    let data = {source, target};
    let path = {
        source: {},
        target: {}
    };
    let has = false;
    
    // 生成地址
    Object.keys(path).forEach((key) =>{
        path[key] = restructure(data[key])
    })

    // 寻找标记点
    Object.keys(path.source).forEach((srouceKey) =>{
        let sourceIden = path.source[srouceKey];

        Object.keys(path.target).forEach((targetKey) =>{
            let targetIden = path.target[targetKey];

            if(sourceIden === targetIden && targetIden !== ''){
                has = true;
                map[srouceKey] = targetKey;
            }
        })
    })
    
    if(!has){console.log('未找到匹配设置')}

    return map
}

// 寻址, end 是否为取值
function addressing (data, pathStr, end){
    let pathArr = pathStr.split('-');
    let lastPath = end ? pathArr.pop() : '';
    let cache;
    
    pathArr.forEach((value, index) =>{
        
        if(!index){
            // 初始值
            cache = data[value];
        }else{
            cache = cache ? cache[value] : "";
        }
    })

    if(end){
        cache = cache === undefined ? data : cache;
        cache[lastPath] = end; 
    }
    
    return cache;
    
}

// 赋值
function assignment (data, template, map){
    
    Object.keys(map).forEach((sourcePath) =>{
        
        let targetPath = map[sourcePath];
        let value = addressing(data, sourcePath);
        
        addressing(template, targetPath, value); 
    })
}

module.exports = {
    addressing,
    restructure,
    creatMap,
    assignment,
    loopData
}